package com.cameron.serviceedu.controller;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cameron.annotation.AdminAuth;
import com.cameron.entity.*;
import com.cameron.servicebase.config.exception.BusinessException;
import com.cameron.serviceedu.client.UserCenterClient;
import com.cameron.serviceedu.entity.viewobject.TeacherQuery;
import com.cameron.serviceedu.service.EduTeacherService;
import com.cameron.serviceedu.service.TeacherApplyService;
import com.cameron.utils.JwtUtils;
import com.cameron.utils.Result;
import com.hooper.util.RandomUtil;
import io.swagger.annotations.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

import static com.cameron.constant.RoleConstant.*;
import static com.cameron.constant.TeacherConstant.*;

/**
 * <p>
 * 讲师 前端控制器
 * </p>
 *
 * @author cameron
 * @since 2022-06-14
 */
@Api(tags = "讲师管理")
@RestController
@RequestMapping("/service/teacher")
@CrossOrigin
public class EduTeacherController {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private EduTeacherService teacherService;

    @Resource
    private TeacherApplyService teacherApplyService;

    @Resource
    private UserCenterClient userCenterClient;

    @ApiOperation("获取所有讲师信息")
    @GetMapping("getAll")
    public Result getAll() {
        String token = stringRedisTemplate.opsForValue().get(TOKEN);
        BackendMemberDto memberDto = JwtUtils.getLoginMemberByToken(token);
        if (StringUtils.isEmpty(token) || memberDto == null) {
            throw new BusinessException(40000, "token expire");
        }
        String teacherJson = stringRedisTemplate.opsForValue().get(TEACHER_LIST_CACHE);
        if (StringUtils.isBlank(teacherJson)) {
            List<EduTeacher> teacherList = teacherService.list(null);
            teacherJson = JSONUtil.toJsonStr(teacherList);
            stringRedisTemplate.opsForValue().set(TEACHER_LIST_CACHE, teacherJson);
        }
        List<EduTeacher> list = JSONUtil.toList(teacherJson, EduTeacher.class);
        if (memberDto.getRoles() == MEMBER_ADMIN) {
            return Result.ok().data("teacherList", list).data("current", null);
        }
        return Result.ok().data("teacherList", list).data("current", memberDto.getId());
    }

    @ApiOperation("删除一名讲师")
    @DeleteMapping("{id}")
    @AdminAuth
    public Result delById(@ApiParam(name = "id", value = "讲师id", required = true) @PathVariable String id) {
        userCenterClient.changeUserRole(id, NORMAL_MEMBER);
        teacherService.removeById(id);
        return Result.ok();
    }

    @ApiOperation("讲师分页查询")
    @AdminAuth
    @GetMapping("page/{currentPage}/{size}")
    public Result page(@PathVariable int currentPage, @PathVariable int size) {
        Page<EduTeacher> page = new Page<>(currentPage, size);
        teacherService.page(page, null);
        List<EduTeacher> records = page.getRecords();
        long total = page.getTotal();
        return Result.ok().data("records", records).data("total", total);
    }

    @ApiOperation("讲师条件分页查询")
    @AdminAuth
    @PostMapping("pageByConditions/{currentPage}/{size}")
    @SuppressWarnings("unchecked")
    public Result pageByConditions(@PathVariable int currentPage, @PathVariable int size,
                                   @RequestBody(required = false) TeacherQuery teacherQuery) {
        //如果对象为空 则表明没有条件 直接调用无条件分页查询即可
        if (teacherQuery == null) {
            return this.page(currentPage, size);
        }
        LambdaQueryWrapper<EduTeacher> lqw = new LambdaQueryWrapper<>();
        if (StringUtils.isEmpty(teacherQuery.getEnd())) {
            teacherQuery.setEnd(LocalDateTime.now().toString());
        }
        //模糊查询
        lqw.like(StringUtils.isNotEmpty(teacherQuery.getName()), EduTeacher::getName, teacherQuery.getName())
                .eq(teacherQuery.getLevel() != null, EduTeacher::getLevel, teacherQuery.getLevel())
                .between(StringUtils.isNotEmpty(teacherQuery.getBegin()),
                        EduTeacher::getGmtCreate, teacherQuery.getBegin(), teacherQuery.getEnd())
                .orderByDesc(EduTeacher::getGmtModified);
        //分页查询
        Page<EduTeacher> page = new Page<>(currentPage, size);
        teacherService.page(page, lqw);
        List<EduTeacher> records = page.getRecords();
        long total = page.getTotal();
        return Result.ok().data("records", records).data("total", total);
    }

    @AdminAuth
    @ApiOperation("添加一名讲师")
    @PostMapping("add")
    public Result add(@RequestBody EduTeacher teacher) {
        teacher.setEmail(RandomUtil.randomEmail());
        //新开一个线程,将讲师信息添加到用户表中
        new Thread(() -> userCenterClient.saveTeacherAsMember(teacher)).start();
        return teacherService.save(teacher) ? Result.ok() : Result.error();
    }

//    @AdminAuth
    @GetMapping("getOne/{id}")
    public Result getOne(@PathVariable String id) {
        String teacherJson = stringRedisTemplate.opsForValue().get(TEACHER_CACHE + id);
        if (StringUtils.isEmpty(teacherJson)){
            EduTeacher teacher = teacherService.getById(id);
            teacherJson = JSONUtil.toJsonStr(teacher);
            stringRedisTemplate.opsForValue().set(TEACHER_CACHE + id, teacherJson);
        }
        return Result.ok().data("info", JSONUtil.toBean(teacherJson, EduTeacher.class));
    }

    @AdminAuth
    @PutMapping("update")
    public Result update(@RequestBody EduTeacher teacher) {
        return teacherService.updateById(teacher) ? Result.ok() : Result.error();
    }

    @PostMapping("apply")
    public Result submitApply(@RequestBody TeacherApplyVo applyVo) {
        String memberId = applyVo.getMemberId();
        String name = applyVo.getName();
        String intro = applyVo.getIntro();
        String career = applyVo.getCareer();
        if (StringUtils.isAnyBlank(memberId, name, intro, career)) {
            throw new BusinessException(40001, "参数为空，请填写必要参数！");
        }
        TeacherApply teacherApply = new TeacherApply();
        LambdaQueryWrapper<TeacherApply> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TeacherApply::getMemberId, applyVo.getMemberId());
        if (teacherApplyService.getOne(wrapper) != null) {
            return Result.error().message("您已申请过讲师，请勿重复申请！");
        }
        teacherApply.setMemberId(applyVo.getMemberId());
        teacherApply.setName(applyVo.getName());
        teacherApply.setIntro(applyVo.getIntro());
        teacherApply.setCareer(applyVo.getCareer());
        teacherApply.setLevel(applyVo.getLevel());
        teacherApply.setApplyTime(new Date());
        teacherApply.setApplyState(APPLYING);
        teacherApplyService.save(teacherApply);
        return Result.ok().message("提交成功！请耐心等待审核。");
    }

    @AdminAuth
    @PostMapping("examine/{id}/{state}")
    @Transactional(rollbackFor = Exception.class)
    public Result examine(@PathVariable Integer state, @PathVariable String id) {
        TeacherApply teacherApply = new TeacherApply();
        teacherApply.setId(id);
        teacherApply.setApplyState(state);
        teacherApplyService.updateById(teacherApply);
        TeacherApply ta = teacherApplyService.getById(id);
        String memberId = ta.getMemberId();
        new Thread(() -> {
            userCenterClient.changeUserRole(memberId, MEMBER_TEACHER);
            //将通过的和拒绝的申请删除
            if (state != 0) teacherApplyService.removeById(id);
        }).start();
        EduTeacher eduTeacher = new EduTeacher();
        eduTeacher.setId(memberId);
        eduTeacher.setName(ta.getName());
        eduTeacher.setIntro(ta.getIntro());
        eduTeacher.setCareer(ta.getCareer());
        eduTeacher.setLevel(ta.getLevel());
        eduTeacher.setAvatar("https://cam-guliedu.oss-cn-beijing.aliyuncs.com/radom-avatar/avatar/" + RandomUtil.randomInt(1, 100) + ".png");
        eduTeacher.setSort(RandomUtil.randomInt(200));
        eduTeacher.setEmail(RandomUtil.randomEmail());
        //将成功申请的用户添加到讲师表中
        new Thread(() -> teacherService.save(eduTeacher)).start();
        return Result.ok().message(state > 0 ? "已通过" : "已拒绝");
    }

    @AdminAuth
    @SuppressWarnings("unchecked")
    @GetMapping("apply/page/{currentPage}/{pageSize}")
    public Result getApplyPage(@PathVariable Integer currentPage, @PathVariable Integer pageSize) {
        Page<TeacherApply> applyPage = new Page<>(currentPage, pageSize);
        LambdaQueryWrapper<TeacherApply> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByAsc(TeacherApply::getApplyTime);
        teacherApplyService.page(applyPage, wrapper);
        return Result.ok().data("applyPage", applyPage);
    }
}

